home *** CD-ROM | disk | FTP | other *** search
- /*
- ** MacSND DataType
- **
- ** Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>
- ** Public domain
- **
- ** :ts=4
- */
-
- #include "Global.h"
-
- // We want to use the locals
-
- #undef SysBase
- #define SysBase SysBase
-
- #undef DOSBase
- #define DOSBase DOSBase
-
- // initCmd opcode controls
-
- #define initMono 0x80 // A monophonic channel, please
- #define initStereo 0xC0 // Two stereo channels, please
-
- // Opcodes to replay sound
-
- #define soundCmd 0x50 // Play a sound or a note
- #define bufferCmd 0x51 // Play a sound
-
- // Offset indicator
-
- #define dataOffsetFlag 0x8000 // Data follows
-
- /* ReadMacBinaryHeader():
- *
- * Read the MacBinary format header and seek to the
- * proper resource location
- */
-
- BOOL __regargs
- ReadMacBinaryHeader(BPTR Handle,LONG *Error,struct ExecBase *SysBase,struct DosLibrary *DOSBase)
- {
- MacBinaryHeader Header;
-
- // No error so far
-
- *Error = 0;
-
- // Read the header, this should be 128 bytes
-
- if(FRead(Handle,&Header,sizeof(MacBinaryHeader),1) == 1)
- {
- LONG Offset;
-
- // The data is found at an odd address...
-
- CopyMem(Header . dflen,&Offset,sizeof(Offset));
-
- // Pad the offset to a multiple of 128, I suppose
- // this is done in order to keep XModem happy
-
- Offset = 128 + ((Offset + 127) & ~127);
-
- // Seek to the resource data location
-
- if(Seek(Handle,Offset,OFFSET_BEGINNING) != -1)
- return(TRUE);
- else
- *Error = ERROR_SEEK_ERROR;
- }
-
- // No success
-
- return(FALSE);
- }
-
- /* ReadSoundHeader():
- *
- * Fill in the BufferCmd data structure
- */
-
- BOOL __regargs
- ReadSoundHeader(BPTR Handle,LONG SoundResourceOffset,struct SoundDataHeader *SoundHeader,LONG *Error,struct ExecBase *SysBase,struct DosLibrary *DOSBase)
- {
- WORD HeaderWords[2],NumCommands,i;
-
- // Read the two header words
-
- if(FRead(Handle,&HeaderWords,sizeof(HeaderWords),1) == 1)
- {
- // Is this a type 1 "snd " resource?
-
- if(HeaderWords[0] == 1)
- {
- // How many synthesizer entries are there?
-
- if(HeaderWords[1])
- {
- struct SynthHeader { WORD ID; LONG Init; } SynthHeader;
-
- // Check all synthesizer init opcodes
-
- for(i = 0 ; !(*Error) && i < HeaderWords[1] ; i++)
- {
- // Read the init header
-
- if(FRead(Handle,&SynthHeader,sizeof(SynthHeader),1) == 1)
- {
- // Stereo sounds are not supported
-
- if((SynthHeader . Init & 0xF0) == initStereo)
- return(FALSE);
- }
- }
- }
- }
- else
- {
- // Only type 1 and type 2 resources are supported
-
- if(HeaderWords[0] < 1 || HeaderWords[0] > 2)
- return(FALSE);
- }
-
- // Read the number of commands to follow
-
- if(FRead(Handle,&NumCommands,sizeof(NumCommands),1) == 1)
- {
- // Are there any commands following?
-
- if(NumCommands)
- {
- struct SoundCommand { UWORD Command; WORD Param1; LONG Param2; } SoundCommand;
-
- // Scan through the commands
-
- for(i = 0 ; !(*Error) && i < NumCommands ; i++)
- {
- // Read the next command
-
- if(FRead(Handle,&SoundCommand,sizeof(SoundCommand),1) == 1)
- {
- // Is this a soundCmd or bufferCmd and does it
- // have data following it?
-
- if(SoundCommand . Command == (dataOffsetFlag | soundCmd) || SoundCommand . Command == (dataOffsetFlag | bufferCmd))
- {
- // Seek to the bufferCmd header
-
- if(Seek(Handle,SoundResourceOffset + SoundCommand . Param2,OFFSET_BEGINNING) != -1)
- {
- // Read the sound header
-
- if(FRead(Handle,SoundHeader,sizeof(struct SoundDataHeader),1) == 1)
- {
- // Compressed sounds are not supported
-
- if(SoundHeader -> Encoding == stdSH)
- {
- // Seek to the location of the data
-
- if(Seek(Handle,SoundHeader -> DataOffset & 0x00FFFFFF,OFFSET_CURRENT) != -1)
- return(TRUE);
- else
- *Error = ERROR_SEEK_ERROR;
- }
- }
- else
- *Error = IoErr();
- }
- else
- *Error = ERROR_SEEK_ERROR;
- }
- }
- else
- *Error = IoErr();
- }
- }
- }
- else
- *Error = IoErr();
- }
- else
- *Error = IoErr();
-
- return(FALSE);
- }
-
- /* ScanResource():
- *
- * Scan a resource file for "snd " resources.
- */
-
- BOOL __regargs
- ScanResource(BPTR Handle,struct SoundDataHeader *SoundHeader,LONG *Error,struct ExecBase *SysBase,struct DosLibrary *DOSBase)
- {
- struct ResourceHeader ResourceHeader;
- struct ResourceMapHeader ResourceMapHeader;
- struct ResourceTypeHeader ResourceTypeHeader;
- struct ResourceTypeEntry ResourceTypeEntry;
- struct ResourceReference ResourceReference;
- LONG Origin = Seek(Handle,0,OFFSET_CURRENT),i,j;
-
- // No error so far
-
- *Error = 0;
-
- // Read the resource header
-
- if(FRead(Handle,&ResourceHeader,sizeof(ResourceHeader),1) == 1)
- {
- // Seek to the resource map
-
- if(Seek(Handle,ResourceHeader . ResourceMapOffset + Origin,OFFSET_BEGINNING) != -1)
- {
- // Read the resource map header
-
- if(FRead(Handle,&ResourceMapHeader,sizeof(ResourceMapHeader),1) == 1)
- {
- // Both the first entries of the resource header and the
- // resource map header must match
-
- if(!memcmp(&ResourceHeader,&ResourceMapHeader,4 * sizeof(LONG)))
- {
- // Seek to the resource type list
-
- if(Seek(Handle,Origin + ResourceHeader . ResourceMapOffset + ResourceMapHeader . ResourceTypeListOffset,OFFSET_BEGINNING) != -1)
- {
- // Read the resource type list header
-
- if(FRead(Handle,&ResourceTypeHeader,sizeof(ResourceTypeHeader),1) == 1)
- {
- // Examine all entries
-
- for(i = 0 ; !(*Error) && i <= ResourceTypeHeader . ResourceEntryCount ; i++)
- {
- // Seek to an entry
-
- if(Seek(Handle,Origin + ResourceHeader . ResourceMapOffset + ResourceMapHeader . ResourceTypeListOffset + sizeof(struct ResourceTypeHeader) + i * sizeof(struct ResourceTypeEntry),OFFSET_BEGINNING) != -1)
- {
- // Read a resource type list entry
-
- if(FRead(Handle,&ResourceTypeEntry,sizeof(ResourceTypeEntry),1) == 1)
- {
- // Examine all resources of this type
-
- for(j = 0 ; !(*Error) && j <= ResourceTypeEntry . ResourceCount ; j++)
- {
- // Seek to the resource reference
-
- if(Seek(Handle,Origin + ResourceHeader . ResourceMapOffset + ResourceMapHeader . ResourceTypeListOffset + ResourceTypeEntry . ResourceReferenceOffset + j * sizeof(struct ResourceReference),OFFSET_BEGINNING) != -1)
- {
- // Read the resource reference header
-
- if(FRead(Handle,&ResourceReference,sizeof(ResourceReference),1) == 1)
- {
- // Is this a "snd " type resource?
-
- if(!memcmp(ResourceTypeEntry . ResourceType,"snd ",4))
- {
- // Seek to the corresponding resource data entry
-
- if(Seek(Handle,Origin + ResourceMapHeader . ResourceDataOffset + (ResourceReference . ResourceInfo & 0xFFFFFF) + sizeof(LONG),OFFSET_BEGINNING) != -1)
- {
- // Process the sound header
-
- if(ReadSoundHeader(Handle,Origin + ResourceMapHeader . ResourceDataOffset + (ResourceReference . ResourceInfo & 0x00FFFFFF) + sizeof(LONG),SoundHeader,Error,SysBase,DOSBase))
- return(TRUE);
- }
- else
- *Error = ERROR_SEEK_ERROR;
- }
- }
- else
- *Error = IoErr();
- }
- else
- *Error = ERROR_SEEK_ERROR;
- }
- }
- else
- *Error = IoErr();
- }
- else
- *Error = ERROR_SEEK_ERROR;
- }
- }
- else
- *Error = IoErr();
- }
- else
- *Error = ERROR_SEEK_ERROR;
- }
- }
- else
- *Error = IoErr();
- }
- else
- *Error = ERROR_SEEK_ERROR;
- }
- else
- *Error = IoErr();
-
- return(FALSE);
- }
-